package han.yang.service.group.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import han.yang.common.ResponseVO;
import han.yang.common.enums.GroupErrorCode;
import han.yang.common.enums.GroupMemberRoleEnum;
import han.yang.service.group.dao.ImGroupMemberEntity;
import han.yang.service.group.dao.mapper.ImGroupMemberMapper;
import han.yang.service.group.model.dto.GroupMemberDto;
import han.yang.service.group.model.req.AddGroupMemberReq;
import han.yang.service.group.model.req.GetJoinedGroupReq;
import han.yang.service.group.model.req.ImportGroupMemberReq;
import han.yang.service.group.model.resp.AddMemberResp;
import han.yang.service.group.model.resp.GetGroupResp;
import han.yang.service.group.model.resp.GetRoleInGroupResp;
import han.yang.service.group.service.ImGroupMemberService;
import han.yang.service.group.service.ImGroupService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Service
public class ImGroupMemberServiceImpl implements ImGroupMemberService {

    @Resource
    ImGroupService imGroupService;

    @Resource
    ImGroupMemberMapper imGroupMemberMapper;

    @Override
    public ResponseVO<?> importGroupMember(ImportGroupMemberReq req) {
        List<AddMemberResp> addMemberResps = new ArrayList<>();
        ResponseVO<?> group = imGroupService.getGroup(req.getGroupId(), req.getAppId());
        if (!group.isOk()){
            return group;
        }
        // 插入
        req.getMembers().forEach( info -> {
            ResponseVO responseVO = null;
            try {
                responseVO = this.addGroupMember(req.getGroupId(),req.getAppId(),info);
            }catch (Exception e){
                e.printStackTrace();
                responseVO = ResponseVO.errorResponse();
            }
            AddMemberResp addMemberResp = new AddMemberResp();
            addMemberResp.setMemberId(info.getMemberId());
            if (responseVO.isOk()) {
                addMemberResp.setResult(0);
            } else if (responseVO.getCode() == GroupErrorCode.USER_IS_JOINED_GROUP.getCode()) {
                addMemberResp.setResult(2);
            } else {
                addMemberResp.setResult(1);
            }
            addMemberResp.setResultMessage(responseVO.getMsg());
            addMemberResps.add(addMemberResp);
        });
        return ResponseVO.successResponse(addMemberResps);
    }

    @Override
    public ResponseVO<GetRoleInGroupResp> getRoleInGroupOne(String groupId, String memberId, Integer appId) {
        QueryWrapper<ImGroupMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_id",groupId);
        queryWrapper.eq("member_id",memberId);
        queryWrapper.eq("app_id",appId);
        GetRoleInGroupResp resp = new GetRoleInGroupResp();
        ImGroupMemberEntity imGroupMemberEntity = imGroupMemberMapper.selectOne(queryWrapper);
        if (imGroupMemberEntity == null ||
                imGroupMemberEntity.getRole() == GroupMemberRoleEnum.LEAVE.getCode()){
            return ResponseVO.errorResponse(GroupErrorCode.MEMBER_IS_NOT_JOINED_GROUP);
        }else {
            resp.setRole(imGroupMemberEntity.getRole());
            resp.setGroupMemberId(imGroupMemberEntity.getGroupMemberId());
            resp.setSpeakDate(imGroupMemberEntity.getSpeakDate());
            resp.setMemberId(imGroupMemberEntity.getMemberId());
            return ResponseVO.successResponse(resp);
        }
    }

    @Override
    public ResponseVO<?> addGroupMember(String groupId, Integer appId, GroupMemberDto dto){
        if (dto.getRole() != null && GroupMemberRoleEnum.OWNER.getCode() == dto.getRole()){
            QueryWrapper<ImGroupMemberEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("group_id",groupId);
            queryWrapper.eq("app_id",appId);
            queryWrapper.eq("role",GroupMemberRoleEnum.OWNER.getCode());
            if (imGroupMemberMapper.selectCount(queryWrapper)>0) {
                return ResponseVO.errorResponse(GroupErrorCode.GROUP_IS_HAVE_OWNER);
            }
        }
        QueryWrapper<ImGroupMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_id",groupId);
        queryWrapper.eq("app_id",appId);
        queryWrapper.eq("member_id",dto.getMemberId());
        ImGroupMemberEntity memberEntity = imGroupMemberMapper.selectOne(queryWrapper);
        long now = System.currentTimeMillis();
        if (memberEntity == null){
            // 初次加群
            memberEntity = new ImGroupMemberEntity();
            memberEntity.setGroupId(groupId);
            memberEntity.setAppId(appId);
            memberEntity.setMemberId(dto.getMemberId());
            memberEntity.setJoinTime(now);
            memberEntity.setRole(dto.getRole());
            memberEntity.setAlias(dto.getAlias());
            int insert = imGroupMemberMapper.insert(memberEntity);
            if (insert != 1){
                return ResponseVO.errorResponse(GroupErrorCode.USER_JOIN_GROUP_ERROR);
            }else return ResponseVO.successResponse();
        }else if (GroupMemberRoleEnum.LEAVE.getCode() == dto.getRole()){
            // 重新加入群
            memberEntity.setJoinTime(now);
            memberEntity.setAlias(dto.getAlias());
            int update = imGroupMemberMapper.update(memberEntity, queryWrapper);
            if (update != 1){
                return ResponseVO.errorResponse(GroupErrorCode.USER_JOIN_GROUP_ERROR);
            }else return ResponseVO.successResponse();
        }
        return ResponseVO.errorResponse(GroupErrorCode.USER_IS_JOINED_GROUP);
    }

    @Override
    public ResponseVO<List<GroupMemberDto>> getGroupMember(String groupId, Integer appId) {
        List<GroupMemberDto> groupMember = imGroupMemberMapper.getGroupMember(appId, groupId);
        return ResponseVO.successResponse(groupMember);
    }

    @Override
    public ResponseVO<Collection<String>> getMemberJoinedGroup(GetJoinedGroupReq req) {
        try {
            Collection<String> joinedGroupId = imGroupMemberMapper.getJoinedGroupId(req);
            return ResponseVO.successResponse(joinedGroupId);
        }catch (Exception e){
            return ResponseVO.errorResponse(null);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseVO transferGroupMember(String owner, String groupId, Integer appId) {
        //更新旧群主
        ImGroupMemberEntity imGroupMemberEntity = new ImGroupMemberEntity();
        imGroupMemberEntity.setRole(GroupMemberRoleEnum.ORDINARY.getCode());
        UpdateWrapper<ImGroupMemberEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("app_id", appId);
        updateWrapper.eq("group_id", groupId);
        updateWrapper.eq("role", GroupMemberRoleEnum.OWNER.getCode());
        imGroupMemberMapper.update(imGroupMemberEntity, updateWrapper);
        //更新新群主
        ImGroupMemberEntity newOwner = new ImGroupMemberEntity();
        newOwner.setRole(GroupMemberRoleEnum.OWNER.getCode());
        UpdateWrapper<ImGroupMemberEntity> ownerWrapper = new UpdateWrapper<>();
        ownerWrapper.eq("app_id", appId);
        ownerWrapper.eq("group_id", groupId);
        ownerWrapper.eq("member_id", owner);
        imGroupMemberMapper.update(newOwner, ownerWrapper);
        return ResponseVO.successResponse();
    }

}
